﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;

namespace Ideal.API.LinqTextQueryBuilder
{
    public class LinqTextQueryBuilder<TSource> where TSource : class
    {

        private TSource _source;

        public LinqTextQueryBuilder()
        {
            Profiler = new LinqTextQueryRuntimeProfiler();
        }
        public LinqTextQueryBuilder( string ns )
            : this()
        {
            if ( ns == null ) throw new ArgumentNullException( "ns" );
            Profiler.AddNamespace( ns );
        }
        public LinqTextQueryBuilder( IEnumerable<Assembly> usedAssemblies, IEnumerable<string> usedNamespaces )
            : this()
        {
            if ( usedAssemblies == null ) throw new ArgumentNullException( "usedAssemblies" );
            if ( usedNamespaces == null ) throw new ArgumentNullException( "usedNamespaces" );
            List<string> usedAssembliesLocations = new List<string>();
            foreach ( var assembly in usedAssemblies )
            {
                usedAssembliesLocations.Add( assembly.Location );
            }
            Profiler.UsedAssembliesLocations = usedAssembliesLocations;
            Profiler.UsedNamespaces = usedNamespaces.ToList();
        }
        public LinqTextQueryBuilder( IEnumerable<string> usedAssembliesLocations, IEnumerable<string> usedNamespaces )
            : this()
        {
            if ( usedAssembliesLocations == null ) throw new ArgumentNullException( "usedAssembliesLocations" );
            if ( usedNamespaces == null ) throw new ArgumentNullException( "usedNamespaces" );
            Profiler.UsedAssembliesLocations = usedAssembliesLocations.ToList();
            Profiler.UsedNamespaces = usedNamespaces.ToList();
        }
        public LinqTextQueryBuilder( IEnumerable<string> usedNamespaces )
            : this()
        {
            if ( usedNamespaces == null ) throw new ArgumentNullException( "usedNamespaces" );
            Profiler.UsedNamespaces = usedNamespaces.ToList();
        }

        public LinqTextQueryRuntimeProfiler Profiler { get; private set; }

        public void SetSource( TSource source )
        {
            _source = source;
        }
        public IList Query( string queryText )
        {
            var runtimeQuery = Profiler.CreateRuntimeQuery<TSource>( queryText );
            return runtimeQuery.ExecuteQuery( _source );
        }



        //public LinqTextQueryBuilder( Assembly assembly, string ns )
        //    : this()
        //{
        //    if ( assembly == null ) throw new ArgumentNullException( "assembly" );
        //    if ( ns == null ) throw new ArgumentNullException( "ns" );
        //    Profiler.AddAssembly( assembly );
        //    Profiler.AddNamespace( ns );
        //}
        //public LinqTextQueryBuilder( string assemblyLocation, string ns )
        //    : this()
        //{
        //    if ( assemblyLocation == null ) throw new ArgumentNullException( "assemblyLocation" );
        //    if ( ns == null ) throw new ArgumentNullException( "ns" );
        //    Profiler.AddAssembly( assemblyLocation );
        //    Profiler.AddNamespace( ns );
        //}

    }

    public class LinqTextQueryBuilder : LinqTextQueryBuilder<IQueryable>
    {

        public LinqTextQueryBuilder()
            : base()
        {
        }
        public LinqTextQueryBuilder( string ns )
            : base( ns )
        {
            if ( ns == null ) throw new ArgumentNullException( "ns" );
            Profiler.AddNamespace( ns );
        }
        public LinqTextQueryBuilder( IEnumerable<Assembly> usedAssemblies, IEnumerable<string> usedNamespaces )
            : base( usedAssemblies, usedNamespaces )
        {
            if ( usedAssemblies == null ) throw new ArgumentNullException( "usedAssemblies" );
            if ( usedNamespaces == null ) throw new ArgumentNullException( "usedNamespaces" );
            List<string> usedAssembliesLocations = new List<string>();
            foreach ( var assembly in usedAssemblies )
            {
                usedAssembliesLocations.Add( assembly.Location );
            }
            Profiler.UsedAssembliesLocations = usedAssembliesLocations;
            Profiler.UsedNamespaces = usedNamespaces.ToList();
        }
        public LinqTextQueryBuilder( IEnumerable<string> usedAssembliesLocations, IEnumerable<string> usedNamespaces )
            : base( usedAssembliesLocations, usedNamespaces )
        {
            if ( usedAssembliesLocations == null ) throw new ArgumentNullException( "usedAssembliesLocations" );
            if ( usedNamespaces == null ) throw new ArgumentNullException( "usedNamespaces" );
            Profiler.UsedAssembliesLocations = usedAssembliesLocations.ToList();
            Profiler.UsedNamespaces = usedNamespaces.ToList();
        }
        public LinqTextQueryBuilder( IEnumerable<string> usedNamespaces )
            : base( usedNamespaces )
        {
            if ( usedNamespaces == null ) throw new ArgumentNullException( "usedNamespaces" );
            Profiler.UsedNamespaces = usedNamespaces.ToList();
        }

    }

}
